package main

func main() {
	/*
		接口的基本概念
		1.接口类型：
			（1）接口字面量类型
				interface {
					MethodSignature1
					MethodSignature2
				}
			（2）接口命名类型
				type InterfaceName interface {
					MethodSignature1
					MethodSignature2
				}
		2.接口定义的大括号内可以是：
			（1）方法声明的集合
			（2）嵌入另一个接口类型匿名字段（就是一个接口类型定义可以包括其他接口）

		3.声明新接口类型的特点：
			（1）接口命名一般以 “er” 结尾
			（2）接口定义的内部的方法声明不需要 func 引导
			（3）接口定义中，只有方法声明，没有方法实现

		4.接口的初始化：
			接口只有被初始化为具体的类型时才有意义，没有初始化的接口变量，默认值为 nil
			（1）接口初始化：接口绑定具体的实例的过程
			（2）初始化的方法：
				1.实例赋值接口：
					具体类型实例的方法是接口的方法集的超集
				2.接口变量赋值接口变量：
					b 的方法集是 a 的子集
						（接口变量 b 绑定的具体实例是接口变量 a 绑定的具体实例的副本）

		5.接口方法的调用的最终地址其实是在运行期决定的（因为可以绑定不同类型的实例），
		将具体类型变量赋值给接口后，会使用具体类型的方法指针初始化接口变量
			注：
			（1）调用接口变量的方法时，实际上是间接的调用实例的方法
			（2）直接调用未初始化的接口变量会发生 panic

		6.接口的：
			动态类型：是接口绑定的具体实例的类型
			静态类型：是接口的方法签名的集合，在其定义时被确定

		7.类型断言：
			（1）i.(TypeName)
					   i: 必须是接口变量（若是具体类型变量会报错）
				TypeName: 可以是 具体类型名 或 接口类型名
						具体类型名：判断接口变量 i 绑定的实例类型是否就是具体类型 TypeName
						接口类型名：判断接口变量 i 绑定的实例类型是否同时实现了 TypeName 接口

			（2）o := i.(TypeName)
				 条件不成立：抛出 panic
				 条件成立：TypeName是
							具体类型名：o 的类型就是 TypeName，变量 o 底层绑定的就是接口绑定的实例值的 副本
							接口类型名：o 的类型就是 TypeName，变量 o 底层绑定的具体类型实例是 i 绑定的实例的 副本

			（3）if o, ok := i.(TypeName); ok {
				}
				若两种情况都不符合，ok = false，此时 o 为 TypeName 类型的“零值”

		8.类型查询：
			只对”接口变量“进行操作
				···查询一个接口变量底层绑定的底层变量的具体类型是什么~
				···查询接口变量绑定的底层变量是否还实现了其他接口类型~

			switch v := i.(type) {          // i 必须为接口变量，若未初始化则为 nil
			case type1:                     // type可以为 具体类型名 / 接口类型名
				//
			case type2:
				//
			default:
				//
			}

		注：fallthrough语句 在 Type switch语句 中不能使用！！！

		9.类型断言 和 类型查询：
			··相同的：
				（1）能判断接口变量绑定的实例的具体类型
				（2）能判断接口变量绑定的实例是否满足另一个接口类型
			··不同点：断言一次只能判断一个类型，查询可以判断多个类型
	*/
}
